package service

import (
	"fmt"
	"log"

	"gitee.com/nggs/microservice/export"
)

type Producer func() export.IService

type factory struct {
	name     string
	producer Producer
}

func newMessageFactory(name string, producer Producer) *factory {
	return &factory{
		name:     name,
		producer: producer,
	}
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
var FM = NewFactoryManager()

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
type FactoryManager struct {
	factories map[string]*factory
}

func NewFactoryManager() *FactoryManager {
	m := &FactoryManager{
		factories: map[string]*factory{},
	}
	return m
}

func (m *FactoryManager) Register(name string, producer Producer) {
	if producer == nil {
		log.Panicf("register service factory fail, producer == nil, name=[%v]", name)
	}

	if f, ok := m.factories[name]; ok {
		log.Panicf("duplicate service factory, id=[%v], factory=[%+v]", name, f)
	}

	m.factories[name] = newMessageFactory(name, producer)
}

func (m *FactoryManager) Produce(name string) (export.IService, error) {
	if factory := m.factories[name]; factory != nil {
		return factory.producer(), nil
	}
	return nil, fmt.Errorf("unsupported service, name=[%s]", name)
}
